#!/usr/bin/env bash
#
# Copyright 2016 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Set PROGram name
PROG=${0##*/}
########################################################################
#+
#+ NAME
#+     $PROG - Changelog updater
#+
#+ SYNOPSIS
#+     $PROG  <tag> [<tag> ...]
#+     $PROG  [--helpshort|--usage|-?]
#+     $PROG  [--help|-man]
#+
#+ DESCRIPTION
#+     Look in kubernetes/CHANGELOG-x.y.md for <tag>'s and update the release
#+     notes with the current ones, prepare a PR and send it out.
#+
#+     $PROG must be run inside of a USER github clone.
#+
#+ OPTIONS
#+     [--help | -man]           - display man page for this script
#+     [--usage | -?]            - display in-line usage
#+
#+ EXAMPLES
#+
#+ FILES
#+
#+ SEE ALSO
#+     common.sh                 - base function definitions
#+     relnotes                  - Used to generate the relesae notes
#+
#+ BUGS/TODO
#+
########################################################################
# If NO ARGUMENTS should return *usage*, uncomment the following line:
usage=${1:-yes}

source $(dirname $(readlink -ne $BASH_SOURCE))/lib/common.sh
source $TOOL_LIB_PATH/gitlib.sh

# Set positional args
TAGS=(${POSITIONAL_ARGV[*]})

###############################################################################
# FUNCTIONS
###############################################################################
###############################################################################
# common::cleanexit prog-specific override function
# Do stuff here to clean up after this specific script
# @param exit code
#
common::cleanexit () {
  tput cnorm

  check_and_clean_branch $WORKBRANCH

  common::timestamp end
  exit ${1:-0}
}


###############################################################################
# If local branch exists return 0, else return 1
# @param branch
#
local_branch_exists () {
  local branch=$1

  # returns code from command
  git rev-parse --verify $branch &>/dev/null
}

###############################################################################
# Check and delete workbranch
# @param branch
check_and_clean_branch () {
  local branch=$1

  if local_branch_exists $branch; then
    if common::askyorn -y "Delete the $branch branch"; then
      logecho -n "Deleting branch $branch: "
      logrun git checkout master
      logrun -s git branch -D $branch
    fi
  fi
}

##############################################################################
# Initialize logs
##############################################################################
# Initialize and save up to 10 (rotated logs)
MYLOG=$TMPDIR/$PROG.log
common::logfileinit $MYLOG 10
# BEGIN script
common::timestamp begin

# Check that you're in a USER-based github clone
git remote -v |egrep -q '^origin.*github.com/kubernetes/kubernetes.*push' \
 && common::exit 1 "Must be in a github.com/<USER>/kubernetes repo."

# Check that the master branch is clean
logecho -n "Checking tree state: "
if [[ -n $(git status -s) ]]; then
  logecho "$FAILED"
  common::exit 1
else
  logecho "$OK"
fi

logecho -n "Checking out master: "
logrun -s git checkout master || common::exit 1

WORKBRANCH="update-${TAGS[0]}"
MARKDOWN_FILE=$TMPDIR/$PROG-md.$$

# Ask and destroy old branch
check_and_clean_branch $WORKBRANCH

# Start a new branch
logecho "Creating and checking out new branch $WORKBRANCH..."
logrun git checkout -b $WORKBRANCH || common::exit 1

for TAG in ${TAGS[*]}; do
  # Check valid TAG
  if [[ $TAG =~ ${VER_REGEX[dotzero]} ]]; then
    logecho "Skipping Major milestone release $TAG..."
    continue
  fi

  if [[ $TAG =~ ${VER_REGEX[release]} ]]; then
    CHANGELOG_FILE="CHANGELOG-${BASH_REMATCH[1]}.${BASH_REMATCH[2]}.md"
  else
    common::exit 1 "Unable to set CHANGELOG file!"
  fi

  # Verify valid and existing tag
  if ! egrep -q "^# $TAG$" $CHANGELOG_FILE; then
    logecho "Skipping - $TAG not found in $CHANGELOG_FILE..."
    continue
  fi

  PREVTAG=$(sed -n "/^# $TAG$/,/^# v/p" $CHANGELOG_FILE |\
            awk '/^## Change(s|log) since / {print $4}')

  logecho -n "Generating new notes for $PREVTAG..$TAG: "
  logrun -s relnotes --quiet $PREVTAG..$TAG \
                     --htmlize-md --markdown-file=$MARKDOWN_FILE

  # Massage the result
  sed -n '/^## Change[a-z]* since '$PREVTAG'$/,${
          /^## Change[a-z]* since '$PREVTAG'$/d;p}' $MARKDOWN_FILE \
   > $TMPDIR/$PROG-tmp.$$

  # Maintain existing spacing layout
  # Strip blank lines at EOF
  sed -i -e :a -e '/^\n*$/{$d;N;};/\n$/ba' $TMPDIR/$PROG-tmp.$$
  echo -e '\n\n' >> $TMPDIR/$PROG-tmp.$$
  logrun mv $TMPDIR/$PROG-tmp.$$ $MARKDOWN_FILE

  # Delete the old entry
  sed -i '/^## Change[a-z]* since '$PREVTAG'$/,/^# v/{//!d}' $CHANGELOG_FILE
  # Insert the new
  sed -i "/^## Change[a-z]* since $PREVTAG$/r $MARKDOWN_FILE" $CHANGELOG_FILE
done

logecho -n "Update $CHANGELOG_FILE TOC: "
common::mdtoc $CHANGELOG_FILE || return 1

if git diff --quiet --exit-code; then
  common::exit 0 "No changes detected.  Nothing to update $PREVTAG..$TAG"
fi

logecho -n "Committing changes for $PREVTAG..$TAG to $CHANGELOG_FILE: "
logrun -s git commit --no-verify -m "Updating release notes for ${TAGS[*]}." \
          $CHANGELOG_FILE

if common::askyorn "Push your change upstream"; then
  logecho
  logecho "Pushing your commit upstream: "
  logrun -s git push origin $WORKBRANCH
else
  logecho
  logecho "Nothing pushed.  Have a look around and push yourself if you like"
  logecho
  logecho "$ git push origin update-$TAG"
  logecho
fi

logrun rm -f $MARKDOWN_FILE

# END script
common::exit 0
